package com.platform.comm.config;

import com.google.common.collect.Maps;
import com.platform.comm.constants.EnumOption;
import com.platform.comm.enums.IEnumOption;
import com.platform.comm.util.ClassScanner;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author liujizheng
 * @version 1.0
 * @ClassName EnumAutoImportConfig
 * @Description 将符合条件的枚举数据注册到spring容器
 * @date 2021/7/8 15:14
 */
@Configuration
@ComponentScan("com.platform")
public class EnumAutoImportConfig {

    private Logger logger = LoggerFactory.getLogger(EnumAutoImportConfig.class);

    /**
     * 是否开启枚举扫描
     */
    @Value("${scan.enable:false}")
    private boolean enable;

    @Value("${scan.package:com.platform}")
    private String basePackage;

    @Bean("enumMapper")
    public Map<String, Class<? extends IEnumOption>> enumMapper() throws IOException {
        if (!enable) {
            return Collections.emptyMap();
        }

        logger.info("开始扫描枚举");
        // 扫描enums包下的枚举类
        List<Class<?>> classList = ClassScanner.scan(basePackage, EnumOption.class);

        Map<String, Class<? extends IEnumOption>> map = Maps.newHashMap();
        for (Class<?> clazz : classList) {
            // 判断是否实现IEnumOption接口
            if (!IEnumOption.class.isAssignableFrom(clazz)) {
                continue;
            }

            Class<? extends IEnumOption> enumOptionClazz = (Class<? extends IEnumOption>) clazz;
            EnumOption annotation = enumOptionClazz.getDeclaredAnnotation(EnumOption.class);
            String name = StringUtils.isEmpty(annotation.name()) ? lowerFirstCase(clazz.getSimpleName()) : annotation.name();
//            if (map.containsKey(name)) {
//                throw new IllegalStateException(String.format("Annotation-specified enum bean name '%s' for bean class [%s] " +
//                                "conflicts with existing, non-compatible enum bean definition of same name and class [%s]",
//                        name, enumOptionClazz.getName(), map.get(name).getName()));
//            }
            map.put(name, enumOptionClazz);
            logger.info("{} mapping to enum map: {key={}, value={}.class}", enumOptionClazz.getName(), name, enumOptionClazz.getSimpleName());
        }
        return map;
    }

    private static final char A = 'A';
    private static final char Z = 'Z';

    /**
     * 首字母转小写
     *
     * @param str 待转换字符串
     * @return 首字母小写字符串
     */
    private static String lowerFirstCase(String str) {
        char[] chars = str.toCharArray();
        if (chars[0] >= A && chars[0] <= Z) {
            // 首字母小写方法，大写会变成小写
            chars[0] += 32;
            return String.valueOf(chars);
        }
        return str;
    }
}
